import 'package:flutter/foundation.dart';
import '../config/upload_config.dart';

/// 上传任务配置
class UploadTaskConfig {
  final String token; // 上传令牌
  final String deviceModel; // 设备型号，用于创建目录
  final bool enableChunk; // 是否启用分片上传
  final int chunkSize; // 分片大小，默认1MB
  final int parallelChunks; // 并行上传分片数量
  final String? albumName; // 相册名称，可选
  final String? baseUrl; // 自定义API基础URL，可选
  final bool optimizeMemory; // 是否使用内存优化模式
  final int directoryId; // 目录ID，指定上传到哪个目录

  UploadTaskConfig({
    required this.token,
    required this.deviceModel,
    this.enableChunk = true,
    this.chunkSize = 1024 * 1024, // 默认1MB
    this.parallelChunks = 3,
    this.albumName,
    this.baseUrl,
    this.optimizeMemory = true, // 默认启用内存优化
    this.directoryId = 0, // 默认为根目录
  });
}

/// 初始化分片上传响应
class ChunkUploadInitResponse {
  final String taskId;
  final String uploadId;
  final int chunkSize;
  final int totalChunks;
  final String expiresAt;

  ChunkUploadInitResponse({
    required this.taskId,
    required this.uploadId,
    required this.chunkSize,
    required this.totalChunks,
    required this.expiresAt,
  });

  factory ChunkUploadInitResponse.fromJson(Map<String, dynamic> json) {
    return ChunkUploadInitResponse(
      taskId: json['task_id'] as String,
      uploadId: json['upload_id'] as String,
      chunkSize: json['chunk_size'] as int,
      totalChunks: json['total_chunks'] as int,
      expiresAt: json['expires_at'] as String,
    );
  }
}

/// 分片上传响应
class ChunkUploadResponse {
  final String taskId;
  final int chunkNumber;
  final String etag;
  final int uploadedChunks;
  final int totalChunks;

  ChunkUploadResponse({
    required this.taskId,
    required this.chunkNumber,
    required this.etag,
    required this.uploadedChunks,
    required this.totalChunks,
  });

  factory ChunkUploadResponse.fromJson(Map<String, dynamic> json) {
    return ChunkUploadResponse(
      taskId: json['task_id'] as String,
      chunkNumber: json['chunk_number'] as int,
      etag: json['etag'] as String,
      uploadedChunks: json['uploaded_chunks'] as int,
      totalChunks: json['total_chunks'] as int,
    );
  }
}

/// 分片状态
class ChunkStatus {
  final int chunkNumber;
  final String status;

  ChunkStatus({required this.chunkNumber, required this.status});

  factory ChunkStatus.fromJson(Map<String, dynamic> json) {
    return ChunkStatus(
      chunkNumber: json['chunk_number'] as int,
      status: json['status'] as String,
    );
  }
}

/// 上传状态响应
class ChunkUploadStatusResponse {
  final String taskId;
  final String fileName;
  final int fileSize;
  final String status;
  final int uploadedChunks;
  final int totalChunks;
  final double progress;
  final List<ChunkStatus> chunks;
  final String createTime;
  final String updateTime;
  final String expiresAt;
  final int directoryId;

  ChunkUploadStatusResponse({
    required this.taskId,
    required this.fileName,
    required this.fileSize,
    required this.status,
    required this.uploadedChunks,
    required this.totalChunks,
    required this.progress,
    required this.chunks,
    required this.createTime,
    required this.updateTime,
    required this.expiresAt,
    this.directoryId = 0,
  });

  // 添加简化构造函数，用于本地构造状态对象
  ChunkUploadStatusResponse.simplified({
    required this.taskId,
    required this.totalChunks,
    required this.uploadedChunks,
    required this.progress,
    this.directoryId = 0,
  }) : fileName = 'local_file',
       fileSize = 0,
       status = 'uploading',
       chunks = [],
       createTime = DateTime.now().toIso8601String(),
       updateTime = DateTime.now().toIso8601String(),
       expiresAt =
           DateTime.now().add(const Duration(hours: 24)).toIso8601String();

  factory ChunkUploadStatusResponse.fromJson(Map<String, dynamic> json) {
    return ChunkUploadStatusResponse(
      taskId: json['task_id'] as String,
      fileName: json['file_name'] as String,
      fileSize: json['file_size'] as int,
      status: json['status'] as String,
      uploadedChunks: json['uploaded_chunks'] as int,
      totalChunks: json['total_chunks'] as int,
      progress: (json['progress'] as num).toDouble(),
      chunks:
          (json['chunks'] as List)
              .map(
                (chunk) => ChunkStatus.fromJson(chunk as Map<String, dynamic>),
              )
              .toList(),
      createTime: json['create_time'] as String,
      updateTime: json['update_time'] as String,
      expiresAt: json['expires_at'] as String,
      directoryId: json['directory_id'] as int? ?? 0,
    );
  }
}

/// 上传完成响应
class ChunkUploadCompleteResponse {
  final int fileId;
  final String filename;
  final String originalFilename;
  final String storagePath;
  final int fileSize;
  final String contentType;
  final String fileType;
  final String createTime;
  final String hash;
  final bool isDuplicate;

  ChunkUploadCompleteResponse({
    required this.fileId,
    required this.filename,
    required this.originalFilename,
    required this.storagePath,
    required this.fileSize,
    required this.contentType,
    required this.fileType,
    required this.createTime,
    required this.hash,
    required this.isDuplicate,
  });

  factory ChunkUploadCompleteResponse.fromJson(Map<String, dynamic> json) {
    return ChunkUploadCompleteResponse(
      fileId: json['file_id'] as int,
      filename: json['filename'] as String,
      originalFilename: json['original_filename'] as String,
      storagePath: json['storage_path'] as String,
      fileSize: json['file_size'] as int,
      contentType: json['content_type'] as String,
      fileType: json['file_type'] as String,
      createTime: json['create_time'] as String,
      hash: json['hash'] as String,
      isDuplicate: json['is_duplicate'] as bool,
    );
  }
}

/// 取消上传响应
class AbortUploadResponse {
  final String taskId;
  final String message;

  AbortUploadResponse({required this.taskId, required this.message});

  factory AbortUploadResponse.fromJson(Map<String, dynamic> json) {
    return AbortUploadResponse(
      taskId: json['task_id'] as String,
      message: json['message'] as String,
    );
  }
}

/// 上传任务状态
enum UploadTaskStatus {
  pending, // 等待上传
  uploading, // 上传中
  paused, // 暂停
  completed, // 完成
  failed, // 失败
  canceled, // 取消
}

/// 上传任务类型
enum UploadTaskType {
  normal, // 普通上传
  chunk, // 分片上传
}

/// 上传任务模型
class UploadTask {
  final String id; // 任务ID
  final String fileName; // 文件名
  final String filePath; // 文件路径
  final int fileSize; // 文件大小
  final String mimeType; // MIME类型
  final UploadTaskType type; // 上传类型
  final UploadTaskStatus status; // 任务状态
  final double progress; // 上传进度 (0-100)
  final String? taskId; // 分片上传任务ID
  final int? totalChunks; // 总分片数
  final int? uploadedChunks; // 已上传分片数
  final int uploadedBytes; // 已上传字节数
  final String? error; // 错误信息
  final DateTime createdAt; // 创建时间
  final DateTime? completedAt; // 完成时间
  final int directoryId; // 目标目录ID
  final String? fileHash; // 文件哈希
  final Map<String, dynamic>? responseData; // 响应数据

  // 用于取消上传的回调
  final Future<void> Function()? cancelCallback;

  UploadTask({
    required this.id,
    required this.fileName,
    required this.filePath,
    required this.fileSize,
    required this.mimeType,
    required this.type,
    required this.status,
    this.progress = 0.0,
    this.taskId,
    this.totalChunks,
    this.uploadedChunks,
    this.uploadedBytes = 0,
    this.error,
    DateTime? createdAt,
    this.completedAt,
    this.cancelCallback,
    this.directoryId = 0,
    this.fileHash,
    this.responseData,
  }) : createdAt = createdAt ?? DateTime.now();

  // 是否是大文件（需要断点上传）
  bool get isLargeFile => fileSize > UploadConfig.largeFileThreshold;

  // 格式化文件大小
  String get formattedSize {
    if (fileSize < 1024) return '$fileSize B';
    if (fileSize < 1024 * 1024)
      return '${(fileSize / 1024).toStringAsFixed(1)} KB';
    if (fileSize < 1024 * 1024 * 1024)
      return '${(fileSize / (1024 * 1024)).toStringAsFixed(1)} MB';
    return '${(fileSize / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB';
  }

  // 获取状态文本
  String get statusText {
    switch (status) {
      case UploadTaskStatus.pending:
        return '等待上传';
      case UploadTaskStatus.uploading:
        return '上传中';
      case UploadTaskStatus.paused:
        return '已暂停';
      case UploadTaskStatus.completed:
        return '已完成';
      case UploadTaskStatus.failed:
        return '上传失败';
      case UploadTaskStatus.canceled:
        return '已取消';
    }
  }

  // 复制并创建新的上传任务实例，仅更新指定的字段
  UploadTask copyWith({
    String? id,
    String? fileName,
    String? filePath,
    int? fileSize,
    String? mimeType,
    UploadTaskType? type,
    UploadTaskStatus? status,
    double? progress,
    String? taskId,
    int? totalChunks,
    int? uploadedChunks,
    int? uploadedBytes,
    String? error,
    DateTime? createdAt,
    DateTime? completedAt,
    Future<void> Function()? cancelCallback,
    int? directoryId,
    String? fileHash,
    Map<String, dynamic>? responseData,
  }) {
    return UploadTask(
      id: id ?? this.id,
      fileName: fileName ?? this.fileName,
      filePath: filePath ?? this.filePath,
      fileSize: fileSize ?? this.fileSize,
      mimeType: mimeType ?? this.mimeType,
      type: type ?? this.type,
      status: status ?? this.status,
      progress: progress ?? this.progress,
      taskId: taskId ?? this.taskId,
      totalChunks: totalChunks ?? this.totalChunks,
      uploadedChunks: uploadedChunks ?? this.uploadedChunks,
      uploadedBytes: uploadedBytes ?? this.uploadedBytes,
      error: error ?? this.error,
      createdAt: createdAt ?? this.createdAt,
      completedAt: completedAt ?? this.completedAt,
      cancelCallback: cancelCallback ?? this.cancelCallback,
      directoryId: directoryId ?? this.directoryId,
      fileHash: fileHash ?? this.fileHash,
      responseData: responseData ?? this.responseData,
    );
  }
}
